package pub.tbc.toolkit.json;

import com.google.gson.*;
import pub.tbc.toolkit.collection.MapBuilder;
import pub.tbc.toolkit.io.Files;

import java.io.File;
import java.lang.reflect.Type;
import java.util.Map;
import java.util.Objects;

/**
 * @author tbc on 2016/8/25 15:57:20.
 */
public final class Gsons {

    private Gsons() {
        throw new AssertionError("No " + getClass() + " instances for you!");
    }

    public static Gson getGsonNoDouble() {
        return new GsonBuilder().
                registerTypeAdapter(Double.class, new JsonSerializer<Double>() {
                    @Override
                    public JsonElement serialize(Double src, Type typeOfSrc, JsonSerializationContext context) {
                        if (src == src.longValue())
                            return new JsonPrimitive(src.longValue());
                        return new JsonPrimitive(src);
                    }
                }).serializeNulls()
                .create();
    }

    public static Gson getGson() {
        return serializeNulls();
    }

    public static Gson serializeNulls() {
        GsonBuilder gsonBuilder = new GsonBuilder();
        return gsonBuilder.serializeNulls().create();
    }

    public static Gson prettyPrinting() {
        GsonBuilder gsonBuilder = new GsonBuilder();
        return gsonBuilder.setPrettyPrinting().create();
    }

    public static String jsonFormatter(String uglyJSONString) {
        Gson gson = new GsonBuilder().setPrettyPrinting().create();
        JsonParser jp = new JsonParser();
        JsonElement je = jp.parse(uglyJSONString);
        return gson.toJson(je);
    }


    private static void test() {
        // 注意这里的Gson的构建方式为GsonBuilder,区别于test1中的Gson gson = new Gson();
        Gson gson = new GsonBuilder()
                .excludeFieldsWithoutExposeAnnotation() // 不导出实体中没有用@Expose注解的属性
                .enableComplexMapKeySerialization() // 支持Map的key为复杂对象的形式
                .serializeNulls() // 连null一起转化
                .setDateFormat("yyyy-MM-dd HH:mm:ss:SSS")// 时间转化为特定格式
                .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)// 会把字段首字母大写,注:对于实体上使用了@SerializedName注解的不会生效.
                .setPrettyPrinting() // 对json结果格式化.
                .setVersion(1.0)// 有的字段不是一开始就有的,会随着版本的升级添加进来,那么在进行序列化和返序列化的时候就会根据版本号来选择是否要序列化.
                // @Since(版本号)能完美地实现这个功能.还的字段可能,随着版本的升级而删除,那么
                // @Until(版本号)也能实现这个功能,GsonBuilder.setVersion(double)方法需要调用.
                .create();
    }


    public static void main(String[] args) {
        File file = new File("D:\\Users\\tbc\\Desktop\\roll-o.txt");
        String json = Files.readString(file);
        String formatJson = jsonFormatter(json);
        System.out.println("json : \n" + json);
        System.out.println("format : \n" + formatJson);
        Map<String, String> map = new MapBuilder<String, String>()
                .put("k1", "v1")
                .put("k2", null)
                .put("k3", 5 + "")
                .toLinkedHashMap();
        System.out.println(getGson().toJson(map));

        System.out.println(Objects.equals("abc", "abc"));
    }

}
